package com.travel.server.manager.impl.command.order;

import com.travel.common.CommonConstant;
import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CommonUtil;
import com.travel.server.manager.dto.request.order.UpdateOrderInfoRequest;
import com.travel.server.manager.dto.response.EmptyResponse;
import com.travel.server.manager.impl.command.AbstractCommand;
import com.travel.server.manager.impl.dal.OrderDal;
import com.travel.server.manager.impl.dal.RefundDal;
import com.travel.server.manager.impl.enums.OrderRefundEnum;
import com.travel.server.manager.impl.enums.OrderStateEnum;
import com.travel.server.manager.impl.enums.OrderStepEnum;
import com.travel.server.manager.impl.sal.OrderSal;
import com.travel.server.manager.impl.sal.OrderStateSal;
import com.travel.server.manager.impl.sal.RefundSal;
import com.travel.server.manager.model.OrderInfo;
import com.travel.server.manager.model.OrderRefundInfo;
import com.travel.server.manager.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @Author: LiZhenhui
 * @Date: 2018/11/5 18:14
 * @Desc:
 */
@Component
@Slf4j
public class UpdateOrderInfoCommand extends AbstractCommand<UpdateOrderInfoRequest, EmptyResponse> {

    @Autowired
    private OrderDal orderDal;

    @Autowired
    private RefundDal refundDal;

    @Override
    protected void checkInput(UpdateOrderInfoRequest request) {
        if(request.getId() == null){
            throwInvalidParam();
        }
    }

    @Override
    public EmptyResponse handle(UpdateOrderInfoRequest request) {
        checkInput(request);
        Date now = new Date();
        UserInfo userInfo = getUserInfo();

        OrderInfo orderInfo = orderDal.selectById(request.getId());
        if(StringUtils.isNotBlank(request.getNote())){
            orderInfo.setNote(orderInfo.getNote() == null? CommonConstant.EMPTY_STR : orderInfo.getNote() + CommonConstant.SEMICOLON_STR + request.getNote());
        }
        if(StringUtils.isNotBlank(request.getStars())){
            if(orderInfo.getStars() != null && orderInfo.getStars().equals(request.getStars())){
                return new EmptyResponse();
            }
            orderInfo.setStars(request.getStars());
        }
        if(StringUtils.isNotBlank(request.getStep())){
            if(request.getStep().equals(orderInfo.getOrderStep())){
                return new EmptyResponse();
            }
            String orderState = OrderStateSal.getStateByStep(request.getStep());
            if(StringUtils.isNotBlank(orderState)){
                orderInfo.setOrderState(orderState);
                if(OrderStateEnum.DELIVERED.getState().equals(orderState)){
                    orderInfo.setDeliveryTime(now);
                    orderInfo.setCompleteTime(null);
                }else if(OrderStateEnum.WAIT_DELIVER.getState().equals(orderState)){
                    orderInfo.setPayTime(now);
                    orderInfo.setPayTime(null);
                    orderInfo.setCompleteTime(null);
                }else if(OrderStateEnum.COMPLETE.getState().equals(orderState)){
                    orderInfo.setCompleteTime(now);
                }else if(OrderStateEnum.WAIT_PAY.getState().equals(orderState)){
                    orderInfo.setPayTime(null);
                    orderInfo.setPayTime(null);
                    orderInfo.setCompleteTime(null);
                }
            }
            if(OrderStepEnum.ORDER_REFUND.getStep().equals(orderInfo.getOrderStep())){
                //当前步骤订单退款改成其他状态，将退款状态置为空
                orderInfo.setRefundState(null);
            }
            if(request.getStep().equals(OrderStepEnum.ORDER_REFUND.getStep())){
                //其他步骤改成订单退款，增加退款状态
                orderInfo.setRefundState(OrderRefundEnum.AGREE.getState());
                //插入一笔退款记录
                insertRefund(orderInfo, userInfo);
            }
            orderInfo.setOrderStep(request.getStep());
        }

        orderInfo.setUpdateTime(now);
        orderInfo.setUpdateBy(userInfo.getName());
        orderDal.insertOrUpdate(orderInfo);

        return new EmptyResponse();
    }

    public void insertRefund(OrderInfo orderInfo, UserInfo userInfo){
        Date now = new Date();
        OrderRefundInfo orderRefundInfo = refundDal.selectByOrderId(orderInfo.getId());
        if(orderRefundInfo != null) {
            if(OrderStateEnum.REFUND_SUCCESS.getState().equals(orderInfo.getOrderState()) && orderRefundInfo.getRefundSuccessTime() == null){
                orderRefundInfo.setRefundSuccessTime(now);
                refundDal.insertOrUpdate(orderRefundInfo);
            }
            return;
        }
        orderRefundInfo = new OrderRefundInfo();
        if(OrderStateEnum.REFUND_SUCCESS.getState().equals(orderInfo.getOrderState())){
            orderRefundInfo.setRefundSuccessTime(now);
        }
        orderRefundInfo.setCreateTime(now);
        orderRefundInfo.setCreateBy(userInfo.getName());
        orderRefundInfo.setOrderId(orderInfo.getId());
        orderRefundInfo.setRefundId(RefundSal.getNewRefundId());
        orderRefundInfo.setRefundAmount(orderInfo.getOrderAmount());
        orderRefundInfo.setUpdateTime(now);
        orderRefundInfo.setUpdateBy(userInfo.getName());
        refundDal.insertOrUpdate(orderRefundInfo);
    }
}
